package com.atguigu.srb.sms.listener;

import com.atguigu.srb.sms.service.SmsService;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Map;

@Component
public class SmsMQListener {
    @Resource
    SmsService smsService;
    //消费发送账户操作短信的消息

    /*
        用户充值成功，给他发送短信：
            1、用户手机号码
            2、本次操作的类型：
                可以判断选择哪个短信模板
            3、操作金额
            4、token：保证幂等性

            使用Map传参:
                mobile : xxx
                type:  '1'  充值
                money:  'xxx'
                token:  uuid
     */
    //mq 交换机 队列  绑定的创建方式：   配置类 @Bean ,     注解
    @RabbitListener(bindings = {
            //一个队列和交换机的绑定对象：
            @QueueBinding(
                   value =  @Queue(
                           name = "sms.acc.queue",
                           durable = Exchange.TRUE,
                           ignoreDeclarationExceptions =  Exchange.TRUE
                   ),
                    exchange = @Exchange(
                            name = "sms.exchange",
                            type = ExchangeTypes.TOPIC,
                            ignoreDeclarationExceptions = Exchange.TRUE
                    ),
                    key = "sms.acc.#"
            )
    })
    public void userAccountListener(Channel channel , Message message, Map<String,String> map) throws IOException {

        try {
            //1、执行消费消息的业务
            String mobile = map.get("mobile");
            String type = map.get("type");
            String money = map.get("money");

            smsService.sendMessage(mobile,null,money);
            //消息消费成功：手动ack
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (Exception e) {
            e.printStackTrace();
            //2、有异常
            if(!message.getMessageProperties().isRedelivered()){
                //2.1 如果是第一次出现异常：让消息重新回到队列 再次消费
                channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
            }else{
                //2.2 如果消息第二次出现异常：第三次消费仍然失败 丢弃消息(如果绑定了死信队列 该消息会进入到死信队列中)
                channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
            }
        }


    }


}
